package com.ymx.darling.executor.mapping.result;

import com.ymx.darling.bean.entity.BeanInfo;
import com.ymx.darling.executor.mapping.relation.RelationType;
import com.ymx.darling.executor.mapping.metadata.MetaData;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 保存结果集的嵌套映射结构
 * @author 爱Java的小于
 */
public class ResultMap {
    private Field field; // 将映射后的数据保存到这个字段中
    private Class<?> module; //映射的类型
    private BeanInfo beanInfo; // 该映射类型的信息封装类
    private MetaData idMetaData; // 该映射类型的的id字段的元数据
    private List<MetaData> metaDataList; // 简单类型字段的映射元数据
    private Map<ResultMap, RelationType> resultMaps; // 映射类型中可能会出现多个级联字段
    private final Map<Object, Object> resultEntityCache = new HashMap<>(); // 缓存映射后的实例

    public void setBeanInfo(BeanInfo beanInfo) {
        this.beanInfo = beanInfo;
    }

    public void setModule(Class<?> module) {
        this.module = module;
    }

    public void setField(Field field) {
        this.field = field;
    }

    public void setIdMetaData(MetaData idMetaData) {
        this.idMetaData = idMetaData;
    }

    public void setMetaDataList(List<MetaData> metaDataList) {
        this.metaDataList = metaDataList;
    }

    public void addResultMaps(ResultMap resultMap, RelationType relationType) {
        if (this.resultMaps == null)
            this.resultMaps = new HashMap<>();
        this.resultMaps.put(resultMap, relationType);
    }

    public BeanInfo getBeanInfo() {
        return beanInfo;
    }

    public Class<?> getModule() {
        return module;
    }

    public Field getField() {
        return field;
    }

    public boolean hasRelationJoinField() {
        return Objects.nonNull(this.resultMaps);
    }

    public List<MetaData> getMetaDataList() {
        return metaDataList;
    }

    public MetaData getIdMetaData() {
        return idMetaData;
    }

    public Map<ResultMap, RelationType> getResultMaps() {
        return resultMaps;
    }

    public boolean hasResultValue(String key) {
        return this.resultEntityCache.containsKey(key);
    }

    public Object getResultValue(String key) {
        return this.resultEntityCache.get(key);
    }

    public void putResultValue(String key, Object value) {
        this.resultEntityCache.put(key, value);
    }
}
